<template>
	<div class="gobang">
		<canvas id="gobang" width="800" height="600"></canvas>
	</div>
</template>

<script>
	const CheckStrWhite = "11111";
	const CheckStrBlack = "22222";
	export default {
		name: "Gobang",
		data() {
			return {
				ctx: null,
				winGame: false,
				whiteTurn: false, // 白棋轮；true-黑棋轮
				resultArr: [] // 记录棋子位置的数组
			};
		},
		mounted() {
			let _this = this;
			let container = document.getElementById("gobang");

			container.addEventListener("click", _this.handleClick);

			_this.ctx = container.getContext("2d");
			_this.ctx.translate(70, 70);
			_this.drawCheckerboard();
		},
		computed: {
			chessText() {
				return this.whiteTurn ? '白棋' : '黑棋';
			}
		},
		methods: {
			drawCheckerboard() {// 画棋盘
				let _this = this;
				_this.ctx.beginPath();
				_this.ctx.fillStyle = "#D7E6C8";
				_this.ctx.rect(0, 0, 450, 450);
				_this.ctx.fill();
				for (var i = 0; i < 15; i++) {
					_this.ctx.beginPath();
					_this.ctx.strokeStyle = "orangered";
					_this.ctx.moveTo(15 + i * 30, 15); //垂直方向画15根线，相距30px;
					_this.ctx.lineTo(15 + i * 30, 435);
					_this.ctx.stroke();
					_this.ctx.moveTo(15, 15 + i * 30); //水平方向画15根线，相距30px;棋盘为14*14；
					_this.ctx.lineTo(435, 15 + i * 30);
					_this.ctx.stroke();

					_this.resultArr.push(new Array(15).fill(0));
				}
				_this.drawText();
			},
			drawChess(x, y) {
				let _this = this;
				let xLine = Math.round((x - 15) / 30); // 竖线第x条
				let yLine = Math.round((y - 15) / 30); // 横线第y条
				if (_this.resultArr[xLine][yLine] !== 0) {
					return;
				}
				let grd = _this.ctx.createRadialGradient(
					xLine * 30 + 15,
					yLine * 30 + 15,
					4,
					xLine * 30 + 15,
					yLine * 30 + 15,
					10
				);
				grd.addColorStop(0, _this.whiteTurn ? "#fff" : "#4c4c4c");
				grd.addColorStop(1, _this.whiteTurn ? "#dadada" : "#000");
				_this.ctx.beginPath();
				_this.ctx.fillStyle = grd;
				_this.ctx.arc(
					xLine * 30 + 15,
					yLine * 30 + 15,
					10,
					0,
					2 * Math.PI,
					false
				);
				_this.ctx.fill();
				_this.ctx.closePath();
				// 判断到谁下了
				_this.setResultArr(xLine, yLine);
				// 判断是否获胜
				_this.checkResult(xLine, yLine);
			},
			setResultArr(m, n) {
				let _this = this;
				_this.resultArr[m][n] = _this.whiteTurn ? 1 : 2; // 白棋为1；黑棋为2

			},

			checkResult(m, n) { // 判断是否有5子相连
				let _this = this;
				let checkStr = _this.whiteTurn ? CheckStrWhite : CheckStrBlack;
				// 取出[m,n]横竖斜四条线的一维数组
				let lineVertical = _this.resultArr[m].join('');
				if (lineVertical.indexOf(checkStr) > -1) {
					_this.winGame = true;
					return;
				}
				let lineHorizontal = [];
				for (let i = 0; i < 15; i++) {
					lineHorizontal.push(_this.resultArr[i][n]);
				}
				lineHorizontal = lineHorizontal.join('');
				if (lineHorizontal.indexOf(checkStr) > -1) {
					_this.winGame = true;
					return;
				}
				let line135 = [];
				for (let j = 0; j < 15; j++) {
					if (m - j >= 0 && n - j >= 0) { // 左上角
						line135.unshift(_this.resultArr[m - j][n - j]);
					}
					if (j > 0 && m + j < 15 && n + j < 15) { // 右下角
						line135.push(_this.resultArr[m + j][n + j]);
					}
				}
				line135 = line135.join('');
				if (line135.indexOf(checkStr) > -1) {
					_this.winGame = true;
					return;
				}
				let line45 = [];
				for (let j = 0; j < 15; j++) {
					if (m + j < 15 && n - j >= 0) { // 右上角
						line45.unshift(_this.resultArr[m + j][n - j]);
					}
					if (j > 0 && m - j >= 0 && n + j < 15) { // 左下角
						line45.push(_this.resultArr[m - j][n + j]);
					}
				}
				line45 = line45.join('');
				if (line45.indexOf(checkStr) > -1) {
					_this.winGame = true;
					return;
				}
			},
			drawText() {
				let _this = this;
				_this.ctx.clearRect(435 + 60, 0, 100, 70);
				_this.ctx.fillStyle = "#fff";
				_this.ctx.font = "20px Arial";
				_this.ctx.fillText('本轮：' + _this.chessText, 435 + 70, 35);
			},
			drawResult() {
				let _this = this;
				_this.ctx.fillStyle = "#ffffff";
				_this.ctx.font = "40px Arial";
				_this.ctx.fillText(_this.chessText + '胜！', 435 + 70, 70);
			},
			handleClick(event) {
				let x = event.offsetX - 70;
				let y = event.offsetY - 70;
				if (x < 15 || x > 435 || y < 15 || y > 435) {
					// 点出界的
					return;
				}
				this.drawChess(x, y);
				if (this.winGame) {
					this.drawResult();
					return;
				}
				this.whiteTurn = !this.whiteTurn;
				this.drawText();
			}
		}
	};
</script>

<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped lang="less">
	.gobang {
		#gobang {
			background: #2a4546;
		}
	}
</style>
